package com.abc.service.impl;

import com.abc.enums.IdType;
import com.abc.service.IdGeneratorService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 基于Redis的分布式ID生成器实现
 * 使用Redis的INCR命令保证ID的唯一性和递增性
 */
@Slf4j
@Service
public class RedisIdGeneratorServiceImpl implements IdGeneratorService {
    
    private static final String ID_KEY_PREFIX = "distributed_id:";
    private static final String DATE_PATTERN = "yyyyMMdd";
    private static final int SEQUENCE_LENGTH = 6; // 序列号长度
    
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    
    @Override
    public String generateId(IdType idType) {
        try {
            // 获取当前日期
            String currentDate = LocalDateTime.now().format(DateTimeFormatter.ofPattern(DATE_PATTERN));
            
            // 构建Redis键名：distributed_id:MESSAGE:20231201
            String redisKey = ID_KEY_PREFIX + idType.getTypeName() + ":" + currentDate;
            
            // 使用Redis的INCR命令获取递增序列号
            Long sequence = stringRedisTemplate.opsForValue().increment(redisKey);
            
            // 设置键的过期时间为2天，避免Redis内存占用过多
            stringRedisTemplate.expire(redisKey, 2, TimeUnit.DAYS);
            
            // 构建最终ID：前缀 + 日期 + 补零的序列号
            // 例如：MSG20231201000001
            String formattedSequence = String.format("%0" + SEQUENCE_LENGTH + "d", sequence);
            String generatedId = idType.getPrefix() + currentDate + formattedSequence;
            
            log.debug("生成分布式ID: {}, 类型: {}, 序列号: {}", generatedId, idType.getTypeName(), sequence);
            
            return generatedId;
            
        } catch (Exception e) {
            log.error("生成分布式ID失败, 类型: {}", idType.getTypeName(), e);
            throw new RuntimeException("生成分布式ID失败", e);
        }
    }
    
    @Override
    public List<String> generateIds(IdType idType) {
        return generateIds(idType, 1);
    }
    
    @Override
    public List<String> generateIds(IdType idType, int count) {
        if (count <= 0) {
            throw new IllegalArgumentException("生成数量必须大于0");
        }
        
        if (count > 1000) {
            throw new IllegalArgumentException("单次生成数量不能超过1000");
        }
        
        List<String> ids = new ArrayList<>(count);
        
        try {
            // 获取当前日期
            String currentDate = LocalDateTime.now().format(DateTimeFormatter.ofPattern(DATE_PATTERN));
            
            // 构建Redis键名
            String redisKey = ID_KEY_PREFIX + idType.getTypeName() + ":" + currentDate;
            
            // 批量获取序列号
            Long startSequence = stringRedisTemplate.opsForValue().increment(redisKey, count);
            
            // 设置键的过期时间
            stringRedisTemplate.expire(redisKey, 2, TimeUnit.DAYS);
            
            // 批量生成ID
            for (int i = 0; i < count; i++) {
                long currentSequence = startSequence - count + 1 + i;
                String formattedSequence = String.format("%0" + SEQUENCE_LENGTH + "d", currentSequence);
                String generatedId = idType.getPrefix() + currentDate + formattedSequence;
                ids.add(generatedId);
            }
            
            log.debug("批量生成分布式ID成功, 类型: {}, 数量: {}, 起始序列号: {}", 
                     idType.getTypeName(), count, startSequence - count + 1);
            
            return ids;
            
        } catch (Exception e) {
            log.error("批量生成分布式ID失败, 类型: {}, 数量: {}", idType.getTypeName(), count, e);
            throw new RuntimeException("批量生成分布式ID失败", e);
        }
    }
}
